package com.cloudkinto.service.company.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.enumType.operate.OperateTypeEnum;
import com.cloudkinto.common.common.MD5Util;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.StringsUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.utils.ali.AliOss;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.CompanyDao;
import com.cloudkinto.dao.CompanyWhiteStorageDao;
import com.cloudkinto.dao.QuotationSchemeDao;
import com.cloudkinto.vo.company.CompanyPageVo;
import com.cloudkinto.vo.warehouse.CompanyWarehouseVo;
import com.cloudkinto.entity.CompanyDo;
import com.cloudkinto.entity.CompanyWhiteStorageDo;
import com.cloudkinto.entity.UserDo;
import com.cloudkinto.service.company.CompanyService;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.role.RoleService;
import com.cloudkinto.service.user.UserService;
import com.cloudkinto.vo.user.UserBuildReq;
import com.cloudkinto.service.warehouse.WarehouseService;
import com.cloudkinto.vo.warehouse.WarehouseRes;
import com.cloudkinto.session.UserSession;
import com.cloudkinto.session.UserSessionManager;
import com.cloudkinto.utils.BeanChangeUtils;
import com.cloudkinto.vo.company.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author 张永远
 * @since 2020-05-27
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class CompanyServiceImpl extends ServiceImpl<CompanyDao, CompanyDo> implements CompanyService {
    @Autowired
    private CompanyDao dao;
    @Autowired
    private OperateRecordService operateRecordService;
    @Autowired
    private WarehouseService warehouseService;
    @Value("${gbc.uploadPath.filePathTemp}")
    private String filePathTemp;
    @Autowired
    private CompanyWhiteStorageDao companyWhiteStorageDao;
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Value("${gbc.uploadPath.filePath}")
    private String filePath;
    @Value("${gbc.uploadPath.fileUrl}")
    private String fileUrl;
    @Autowired
    private UserSessionManager userSessionManager;
    @Autowired
    private QuotationSchemeDao quotationSchemeDao;

    @Override
    public SingleResult addInit() {
        return SingleResult.success("");
    }

    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success("");
    }

    /**
     * 操作日志
     *
     * @param ot
     * @param nt
     * @return
     */
    public String getOperateContent(CompanyDo ot, CompanyDo nt) {
        Map<String, Object> beforeMap = new HashMap<>();
        Map<String, Object> afterMap = new HashMap<>();
        BeanChangeUtils<CompanyDo> utils = new BeanChangeUtils<>();
        utils.contrastObj(ot, nt, beforeMap, afterMap);
        StringBuilder content = new StringBuilder();
        for (String key : beforeMap.keySet()) {
            String name = StaticDict.Operate_Log_Company.getText(key);
            int type = StaticDict.Operate_Log_Company.getType(key);

            if ("".equals(name)) {
                continue;
            }
            if (content.length() > 0) {
                content.append(";\r\n");
            }
            content.append(name).append("【");
            String before = type == 0 ? beforeMap.get(key).toString() : (beforeMap.get(key).equals(0) ? "是" : "否");
            content.append(before).append("】").append("->【");
            String after = type == 0 ? afterMap.get(key).toString() : (afterMap.get(key).equals(0) ? "是" : "否");
            content.append(after).append("】");
        }
        return content.toString();
    }

    @Override
    public Object update(CompanyUpdateReq req, Long tenantId, Long userId) {
        CompanyDo ot = dao.selectById(req.getId());
        List<String> list = this.companyUpdateCheck(req, req.getId(), req.getAdminAccountId(), true);
        if (!list.isEmpty()) throw new BizException(list.get(0));
        CompanyDo companyDo = new CompanyDo();
        BeanUtils.copyProperties(req, companyDo);
        companyDo.setUpdateBy(userId);
        companyDo.setUpdateTime(new Date());
        companyDo.setId(req.getId());
        dao.updateById(companyDo);
        //仓库
        this.setStorage(new CompanySetStorageReq(companyDo.getId(), req.getStorage()), tenantId, userId);
        //OMS管理员账号
//        UserDo userDo = userService.getById(req.getAdminAccountId());
//        if (userDo != null) {
//            userDo.setUserAccount(req.getAdminAccount());
//            userDo.setUpdateBy(userId);
//            userDo.setUpdateTime(new Date());
//            userService.updateById(userDo);
//        }
        CompanyDo nt = dao.selectById(req.getId());
        String operateContent = this.getOperateContent(ot, nt);
        operateRecordService.operateAddRecordAndValue(operateContent, "", companyDo.getId(), userId, null, OperateTypeEnum.Company);

        return null;
    }


    @Override
    public int delete(Long id, Long userId) {
        CompanyDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(CompanyDo entityDo, Long userId) {
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_TRUE);

    }

    @Override
    public CompanyDetailRes detail(Long id, Long userId, Long tenantId, String source) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("source", source);
        map.put("userId", userId);
        List<CompanyPageVo> list = dao.list(map);
        if (list.isEmpty()) throw new BizException(SysConstant.No_Data);
        CompanyDetailRes res = new CompanyDetailRes();
        BeanUtils.copyProperties(list.get(0), res);
        res.setOperateResList(operateRecordService.getOperateList(id, OperateTypeEnum.Company));
        res.setStorage(warehouseService.getWarehouseCompany(id, tenantId));
        return res;
    }

    //查询明细之后要执行的业务定制处理
    private Object handlerDetailAfter(Object res) {
        return res;
    }

    @Override
    public SingleResult pageInit() {
        return SingleResult.success("");
    }


    @Override
    public List<Map> getInitList(Long companyId) {
        List<Map> list = new ArrayList<>();
        QueryWrapper wrapper2 = new QueryWrapper();
        if (companyId != null) {
            wrapper2.eq("id", companyId);
        }
        List<CompanyDo> companyDos = list(wrapper2);
        for (CompanyDo c : companyDos) {
            Map<String, String> map = new HashMap<>();
            map.put("id", c.getId() + "");
            map.put("value", c.getCompanyCode());
            map.put("name", c.getName());
            list.add(map);
        }
        return list;
    }

//    @Override
//    public List<Map<String, Object>> getList(Long tenantId) {
//            List<Map<String, Object>> mapList = new ArrayList<>();
//            Map<String, Object> param = new HashMap<>();
//            param.put("tenantId", tenantId);
//            List<CompanyPageDto> companyDos = this.getList(param);
//            companyDos.forEach(companyDo -> {
//                Map<String, Object> map = new HashMap<>();
//                map.put("id", companyDo.getId());
//                map.put("value", companyDo.getCompanyCode());
//                map.put("name", companyDo.getName());
//                mapList.add(map);
//            });
//            return mapList;
//        }


    /**
     * 获取租户下 所有客户列表 不受权限控制
     *
     * @param map
     * @return
     */
    @Override
    public List<CompanyPageVo> getListNoPower(Map<String, Object> map) {
        map.put("source", "wms");
        List<CompanyPageVo> list = dao.list(map);
        return list;
    }

    @Override
    public List<CompanyPageVo> getList(Map<String, Object> map) {
        List<CompanyPageVo> list = dao.list(map);
        return list;
    }

    @Override
    public PageResult getListPage(Map<String, Object> map) {
        IPage<CompanyPageVo> page = pageInitDto(map);
        page = dao.list(page, map);
        PageResult result = new PageResult(page.getRecords(), (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }


    private IPage<CompanyPageVo> pageInitDto(Map<String, Object> map) {
        IPage<CompanyPageVo> page = new Page<>();
        page.setSize((map.get("pageSize") != null) ? Long.parseLong(map.get("pageSize").toString()) : 10);
        page.setCurrent((map.get("current") != null) ? Long.parseLong(map.get("current").toString()) : 1);
        return page;
    }

    @Override
    public List<CompanyRes> getCompanyList(Long userId, Long tenantId, String source) {
        List<CompanyDo> companyDos = dao.getCompanyList(userId, tenantId, source);
        List<CompanyRes> list = new ArrayList<>();
        for (CompanyDo companyDo : companyDos) {
            list.add(new CompanyRes(companyDo.getId(), companyDo.getTenantId(), companyDo.getName(), companyDo.getCompanyCode()));
        }
        return list;
    }

    public List<String> companyAddCheck(CompanyAddReq req, boolean one) {
        return this.companyUpdateCheck(req, null, null, one);
    }

    public List<String> companyUpdateCheck(CompanyAddReq req, Long id, Long adminAccountId, boolean one) {
        List<String> errors = new ArrayList<>();
        if (StringUtils.isBlank(req.getName())) {
            errors.add(SysConstant.Company_Add_Name_Empty);
            if (one) return errors;
        } else {
            CompanyDo et = dao.selectOne(new LambdaQueryWrapper<CompanyDo>()
                    .ne(id != null, CompanyDo::getId, id)
                    .eq(CompanyDo::getName, req.getName().trim()).last(" limit 1"));
            if (et != null) {
                errors.add(SysConstant.Company_Add_Name_Same);
                if (one) return errors;
            }
        }
        if (StringUtils.isBlank(req.getContact())) {
            errors.add(SysConstant.Company_Add_Concat_Empty);
            if (one) return errors;
        }
        if (StringUtils.isBlank(req.getTel())) {
            errors.add(SysConstant.Company_Add_Tel_Empty);
            if (one) return errors;
        }
        if (StringUtils.isBlank(req.getEmail())) {
            errors.add(SysConstant.Company_Add_Email_Empty);
            if (one) return errors;
        } else {
            String regex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}";
            if (!req.getEmail().trim().matches(regex)) {
                errors.add(SysConstant.Company_Add_Email_Format);
                if (one) return errors;
            }
        }
        //OMS管理员账号
        if (StringUtils.isBlank(req.getAdminAccount())) {
            errors.add(SysConstant.Company_Add_OmsAdmin_Empty);
            if (one) return errors;
        } else {
            UserDo userDo = userService.getOne(new LambdaQueryWrapper<UserDo>()
                    .ne(adminAccountId != null, UserDo::getId, adminAccountId)
                    .eq(UserDo::getUserAccount, req.getAdminAccount().trim()).last(" limit 1"));
            if (userDo != null) {
                errors.add(SysConstant.Company_Add_OmsAdmin_Same);
                if (one) return errors;
            }
        }
        return errors;
    }

    @Override
    public void addCompany(CompanyAddReq req, Long tenantId, Long userId, boolean needCheck) {
        if (needCheck) {
            List<String> list = this.companyAddCheck(req, true);
            if (!list.isEmpty()) throw new BizException(list.get(0));
        }
        CompanyDo companyDo = new CompanyDo();
        BeanUtils.copyProperties(req, companyDo);
        companyDo.setCreateBy(userId);
        companyDo.setCreateTime(new Date());
        companyDo.setTenantId(tenantId);
        dao.insert(companyDo);
        StringBuilder companyCode = new StringBuilder(companyDo.getId() + "");
        while (companyCode.length() < 3) {
            companyCode.insert(0, 0);
        }
        companyCode.insert(0, "C1");
        companyDo.setCompanyCode(companyCode.toString());
        dao.updateById(companyDo);
        operateRecordService.operateAddRecordAndValue("创建客户", "", companyDo.getId(), userId, null, OperateTypeEnum.Company);
        //添加默认角色
        Long roleId = roleService.ompAdminRoleAddForCompany(companyDo.getId(), userId, tenantId);
        //添加管理员账号
        UserBuildReq userBuildReq = new UserBuildReq(req.getAdminAccount(), req.getAdminAccount(), SysConstant.Admin_Account_Initial_Password, roleId, req.getEmail(), req.getTel());
        userService.add(userBuildReq, userId, companyDo.getId(), tenantId, "oms");
        //仓库
        this.setStorage(new CompanySetStorageReq(companyDo.getId(), req.getStorage()), tenantId, userId);

    }

    /**
     * 配置可用仓
     */
    @Override
    public void setStorage(CompanySetStorageReq req, Long tenantId, Long userId) {
        if (req.getId() == null) throw new BizException(SysConstant.No_Data);

        Map<Long, String> storageMap = req.getStorage().stream().collect(Collectors.toMap(CompanyWarehouseVo::getStorageId, i -> i.getWhNameCn() + "(" + i.getWhCode() + ")"));


        //获取旧的可用仓
        List<CompanyWarehouseVo> warehouses = warehouseService.getWarehouseCompany(req.getId(), tenantId);
        List<Long> oldStorageIds = warehouses.stream().filter(i -> i.getSelected() == 1).map(CompanyWarehouseVo::getStorageId).distinct().collect(Collectors.toList());
        List<Long> newStorageIds = req.getStorage().stream().filter(i -> i.getSelected() == 1).map(CompanyWarehouseVo::getStorageId).distinct().collect(Collectors.toList());

        //要删除的仓库
        List<Long> delete = oldStorageIds.stream().filter(i -> !newStorageIds.contains(i)).distinct().collect(Collectors.toList());
        //要新增的
        List<Long> insert = newStorageIds.stream().filter(i -> !oldStorageIds.contains(i)).distinct().collect(Collectors.toList());
        //删除
        for (Long whId : delete) {
            //判断 根据仓库 客户id 寻找是否 关联报价方案
            int count = quotationSchemeDao.getQsByForSetStorage(req.getId(), whId);
            if (count > 0) {
                throw new BizException(SysConstant.Storage_HadData_WithName, storageMap.get(whId));
            }
        }
        if (!delete.isEmpty()) companyWhiteStorageDao.updateDelete(delete, req.getId(), userId);
        //新增
        for (Long storageId : insert) {
            CompanyWhiteStorageDo storageDo = new CompanyWhiteStorageDo();
            storageDo.setCompanyId(req.getId());
            storageDo.setStorageId(storageId);
            storageDo.setCreateBy(userId);
            companyWhiteStorageDao.insert(storageDo);
        }
        List<WarehouseRes> list = warehouseService.getList(tenantId);
        Map<Long, List<WarehouseRes>> collect = list.stream().collect(Collectors.groupingBy(WarehouseRes::getId));
        StringBuilder operateValue = new StringBuilder();
        if (!insert.isEmpty()) {
            StringBuilder insertValue = new StringBuilder();
            for (Long storageId : insert) {
                List<WarehouseRes> warehouseRes = collect.get(storageId);
                if (warehouseRes.isEmpty()) continue;
                if (insertValue.length() > 0) insertValue.append("、");
                insertValue.append(warehouseRes.get(0).getWhNameCn()).append("(").append(warehouseRes.get(0).getWhCode()).append(")");
            }
            insertValue.append("】");
            insertValue.insert(0, "添加可用仓库:【");
            operateValue.append(insertValue);
        }
        if (!delete.isEmpty()) {
            StringBuilder deleteValue = new StringBuilder();
            for (Long storageId : delete) {
                List<WarehouseRes> warehouseRes = collect.get(storageId);
                if (warehouseRes.isEmpty()) continue;
                if (deleteValue.length() > 0) deleteValue.append("、");
                deleteValue.append(warehouseRes.get(0).getWhNameCn()).append("(").append(warehouseRes.get(0).getWhCode()).append(")");
            }
            deleteValue.append("】");
            deleteValue.insert(0, "取消可用仓库:【");
            operateValue.append(deleteValue);
        }
        operateRecordService.operateAddRecordAndValue(operateValue.toString(), "", req.getId(), userId, null, OperateTypeEnum.Company);


    }


    @Override
    public void productFreeTrial(ProductFreeTrialReq req, Long userId) {
        CompanyDo ot = dao.selectById(req.getId());
        if (ot == null) throw new BizException(SysConstant.No_Data);
        if (req.getProductFreeTrial() == ot.getProductFreeTrial()) return;
        CompanyDo et = new CompanyDo();
        et.setId(req.getId());
        et.setProductFreeTrial(req.getProductFreeTrial());
        et.setUpdateBy(userId);
        dao.updateById(et);
        CompanyDo nt = dao.selectById(req.getId());
        String operateContent = this.getOperateContent(ot, nt);

        operateRecordService.operateAddRecordAndValue(operateContent, "", et.getId(), userId, null, OperateTypeEnum.Company);
    }

    @Override
    public void updateStatus(UpdateStatusReq req, Long userId) {
        CompanyDo et = dao.selectById(req.getId());
        if (req.getStatus() == et.getStatus()) return;
        et.setStatus(req.getStatus());
        et.setUpdateBy(userId);
        dao.updateById(et);

        //更新账号
        LambdaUpdateWrapper<UserDo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserDo::getCompanyId, req.getId());
        updateWrapper.set(UserDo::getUserStatus, req.getStatus() == 1 ? 2 : 1);
        userService.update(updateWrapper);

        operateRecordService.operateAddRecordAndValue(req.getStatus() == 0 ? SysConstant.Company_Status_0 : SysConstant.Company_Status_1, "", et.getId(), userId, null, OperateTypeEnum.Company);
    }

    @Override
    public void resetPassword(ResetPasswordReq req, Long userId) {
        CompanyDo et = dao.selectById(req.getId());
        if (et == null) throw new BizException(SysConstant.No_Data);
        //获取管理员账号
        List<UserDo> userDos = dao.getAdminUserAccount(req.getId());
        for (UserDo userDo : userDos) {
            MD5Util md5 = new MD5Util(SysConstant.SALT_STRING, "MD5");
            userDo.setUserPassword(md5.encode(SysConstant.Admin_Account_Initial_Password));
            userDo.setUpdateBy(userId);
            userDo.setUpdateTime(new Date());
            userService.updateById(userDo);
        }
    }

    @Override
    /**
     * 下载客户段模板
     */
    public void templateDownload(Long tenantId, HttpServletResponse response) {
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
        XSSFSheet sheet = xssfWorkbook.createSheet();
        //获取仓库信息
        List<WarehouseRes> warehouses = warehouseService.getList(tenantId);
        List<String> headers = this.getHeader();
        int fixedHeaderSize = headers.size();
        for (WarehouseRes warehouse : warehouses) {
            headers.add(warehouse.getWhNameCn());
        }

        XSSFRow titleRow = sheet.createRow(0);//第一行
        sheet.setColumnWidth(0, 256 * 25);
        sheet.setColumnWidth(1, 256 * 25);
        sheet.setColumnWidth(2, 256 * 20);
        sheet.setColumnWidth(3, 256 * 20);
        sheet.setColumnWidth(4, 256 * 15);
        sheet.setColumnWidth(5, 256 * 15);
        sheet.setColumnWidth(6, 256 * 40);
        sheet.setColumnWidth(7, 256 * 20);

        // 创建下拉列表数据验证助手
        XSSFDataValidationHelper dataValidationHelper = new XSSFDataValidationHelper(sheet);
        for (int i = 0; i < headers.size(); i++) {
            XSSFCell firstRowCell = titleRow.createCell(i);
            firstRowCell.setCellValue(headers.get(i));
            if (i == 0 || i == 2 || i == 3 || i == 4 || i == 7 || i == 6) {
                firstRowCell.setCellStyle(ExcelUtils.getStyle(xssfWorkbook, true, IndexedColors.YELLOW.getIndex(), true));
            } else {
                firstRowCell.setCellStyle(ExcelUtils.getStyle(xssfWorkbook, true, IndexedColors.GREY_25_PERCENT.getIndex(), true));
            }
            if (i >= fixedHeaderSize - 1) {
                // 设置下拉列表的四个角坐标
                CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(0, 65535, i, i); // A1单元格
                // 创建下拉列表的选项
                DataValidationConstraint constraint = dataValidationHelper.createExplicitListConstraint((i == fixedHeaderSize - 1 ? new String[]{"是", "否"} : new String[]{"可用", "不可用"}));

                // 创建下拉列表
                DataValidation dataValidation = dataValidationHelper.createValidation(constraint, cellRangeAddressList);
                // 设置下拉列表
                sheet.addValidationData(dataValidation);
            }
        }
        titleRow.setHeight((short) 1000);
        String fileName = "客户列表导入" + TimeUtils.getCurrentDateFormat("MMddHHmmss") + ".xlsx";

        ExcelUtils.exportUtils(xssfWorkbook, fileName, filePathTemp, response);
//        //写道文件里 已文件得形式返回
//        String filePathLocal = filePathTemp;
//        File file = new File(filePathLocal);
//        if (!file.exists()) {
//            file.mkdirs();
//        }
//        filePathLocal += File.separator + fileName;
//        OutputStream outputStream = null;
//        try {
//            outputStream = new FileOutputStream(filePathLocal);
//        } catch (FileNotFoundException e) {
//            throw new RuntimeException(e);
//        }
//        //先保存到临时路径，在通过文件上传的方法上传到正式路径
//        try {
//            xssfWorkbook.write(outputStream);
//            xssfWorkbook.close();
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
    }

    public List<String> getHeader() {
        return new ArrayList<>(Arrays.asList("CustomerName/客户名称", "Company name/公司名称", "Contacter/联系人", "Telephone/电话", "Email/邮箱", "Address/地址", "OMS administrator account/OMS管理员账户", "是否审核产品"));
    }

    @Override
    public CompanyImportRes templateImport(MultipartFile file, Long tenantId, Long userId) {
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) && !GlobalConstants.IMG_TYPE_CSV.equals(suffix.toUpperCase())
                && !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            throw new BizException(SysConstant.File_Form_Incorrect);
        }

        XSSFWorkbook xssfWorkbook = null;
        try {
            xssfWorkbook = new XSSFWorkbook(file.getInputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
        //获取仓库信息
        List<WarehouseRes> warehouseList = warehouseService.getList(tenantId);
        List<String> headers = this.getHeader();

        List<CompanyAddReq> importVos = new ArrayList<>();
        for (int i = 1; i <= sheetAt.getLastRowNum(); i++) {
            XSSFRow row = sheetAt.getRow(i);

            CompanyAddReq importVo = new CompanyAddReq();
            for (int h = 0; h < headers.size(); h++) {
                row.getCell(h).setCellType(CellType.STRING);
            }
            importVo.setName(row.getCell(0).getStringCellValue());
            importVo.setCompanyName(row.getCell(1).getStringCellValue());
            importVo.setContact(row.getCell(2).getStringCellValue());
            importVo.setTel(row.getCell(3).getStringCellValue());
            importVo.setEmail(row.getCell(4).getStringCellValue());
            importVo.setAddress(row.getCell(5).getStringCellValue());
            importVo.setAdminAccount(row.getCell(6).getStringCellValue());
            String productFree = row.getCell(7).getStringCellValue();
            importVo.setProductFreeTrial(StringUtils.isBlank(productFree) || "否".equals(productFree) ? 0 : 1);
            //仓库情况
            List<CompanyWarehouseVo> storage = new ArrayList<>();
            for (int w = 1; w <= warehouseList.size(); w++) {
                CompanyWarehouseVo warehouseVo = new CompanyWarehouseVo();
                XSSFCell cell = row.getCell(headers.size() + w - 1);
                WarehouseRes ware = warehouseList.get(w - 1);
                if (cell == null) {
                    continue;
                } else {
                    cell.setCellType(CellType.STRING);
                    if (cell.getStringCellValue() != null && "可用".equals(cell.getStringCellValue())) {
                        warehouseVo.setSelected(1);
                        warehouseVo.setStorageId(ware.getId());
                        warehouseVo.setWhNameCn(ware.getWhNameCn());
                        warehouseVo.setWhCode(ware.getWhCode());
                        warehouseVo.setTenantId(tenantId);
                    } else {
                        continue;
                    }
                }
                storage.add(warehouseVo);
            }
            importVo.setStorage(storage);
            importVos.add(importVo);
//            this.addCompany(importVo, tenantId, userId);
        }
        List<CompanyAddErrorExportVo> errors = new ArrayList<>();
        for (CompanyAddReq importVo : importVos) {
            List<String> list = this.companyAddCheck(importVo, true);
            if (!list.isEmpty()) {
                CompanyAddErrorExportVo exportVo = new CompanyAddErrorExportVo();
                BeanUtils.copyProperties(importVo, exportVo);
                exportVo.setErrors(list);
                errors.add(exportVo);
                continue;
            }
            this.addCompany(importVo, tenantId, userId, false);
        }
        if (errors.isEmpty()) return new CompanyImportRes(importVos.size());

        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        XSSFRow titleRow = sheet.createRow(0);//第一行
        sheet.setColumnWidth(0, 256 * 70);
        sheet.setColumnWidth(1, 256 * 25);
        sheet.setColumnWidth(2, 256 * 25);
        sheet.setColumnWidth(3, 256 * 20);
        sheet.setColumnWidth(4, 256 * 20);
        sheet.setColumnWidth(5, 256 * 15);
        sheet.setColumnWidth(6, 256 * 15);
        sheet.setColumnWidth(7, 256 * 40);
        sheet.setColumnWidth(8, 256 * 20);
        headers.add(0, "Error/错误原因");
        //获取仓库信息
        for (WarehouseRes warehouse : warehouseList) {
            headers.add(warehouse.getWhNameCn());
        }
        for (int i = 0; i < headers.size(); i++) {
            XSSFCell firstRowCell = titleRow.createCell(i);
            firstRowCell.setCellValue(headers.get(i));
            if (i == 1 || i == 3 || i == 4 || i == 5 || i == 8 || i == 7) {
                firstRowCell.setCellStyle(ExcelUtils.getStyle(workbook, true, IndexedColors.YELLOW.getIndex(), true));
            } else {
                firstRowCell.setCellStyle(ExcelUtils.getStyle(workbook, true, IndexedColors.GREY_25_PERCENT.getIndex(), true));
            }
        }
        titleRow.setHeight((short) 1000);
        String fileName = "错误_客户列表导入" + TimeUtils.getCurrentDateFormat("MMddHHmmss") + ".xlsx";
        for (int i = 0; i < errors.size(); i++) {
            XSSFRow row = sheet.createRow(i + 1);//第i+1行

            for (int h = 0; h < headers.size(); h++) {
                XSSFCell cell = row.createCell(h);
                if (h == 0) {
                    StringBuilder error = new StringBuilder();
                    for (String s : errors.get(i).getErrors()) {
                        if (error.length() > 0) error.append(";");
                        error.append(StringsUtil.createI18Message(s));
                    }
                    cell.setCellValue(error.toString());
                } else if (h == 1) {
                    cell.setCellValue(errors.get(i).getName());
                } else if (h == 2) {
                    cell.setCellValue(errors.get(i).getCompanyName());
                } else if (h == 3) {
                    cell.setCellValue(errors.get(i).getContact());
                } else if (h == 4) {
                    cell.setCellValue(errors.get(i).getTel());
                } else if (h == 5) {
                    cell.setCellValue(errors.get(i).getEmail());
                } else if (h == 6) {
                    cell.setCellValue(errors.get(i).getAddress());
                } else if (h == 7) {
                    cell.setCellValue(errors.get(i).getAdminAccount());
                } else if (h == 8) {
                    cell.setCellValue(errors.get(i).getProductFreeTrial() == 0 ? "否" : "是");
                }
            }
            for (int w = 0; w < warehouseList.size(); w++) {
                XSSFCell cell = row.createCell(headers.size() + w - warehouseList.size()); //此时header 已经加上了 仓库的长度
                cell.setCellValue(errors.get(i).getStorage().get(w).getSelected() == 0 ? "不可用" : "可用");
            }
        }
        String filePathLocal = filePathTemp;
        File fileDo = new File(filePathLocal);
        if (!fileDo.exists()) {
            fileDo.mkdirs();
        }
        filePathLocal += File.separator + fileName;
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(filePathLocal);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        //先保存到临时路径，在通过文件上传的方法上传到正式路径
        try {
            workbook.write(outputStream);
            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        CompanyImportRes res = new CompanyImportRes();
        String objectNameTemporary = "";
        if (filePath.startsWith("http")) {
            try {
                objectNameTemporary = AliOss.temporaryFile2(fileName, new File(filePathLocal));
            } catch (Exception e) {
                e.printStackTrace();
                log.error("导出文件失败" + e.getMessage());
            }
            res.setFailFileUrl(fileUrl + objectNameTemporary);
        } else {
            res.setFailFileUrl(fileUrl + fileName);
        }
        res.setFileName(fileName);
        res.setFailNum(errors.size());
        res.setSuccessNum(importVos.size() - errors.size());
        return res;
    }

    @Override
    public void companyExport(Map<String, Object> map, HttpServletResponse response) {
        List<CompanyPageVo> list = dao.list(map);
        List<CompanyExportVo> exportVos = new ArrayList<>();
        for (CompanyPageVo companyPageVo : list) {
            CompanyExportVo exportVo = new CompanyExportVo();
            BeanUtils.copyProperties(companyPageVo, exportVo);
            exportVos.add(exportVo);
        }
        String fileName = "客户列表导出" + TimeUtils.getCurrentDateFormat("MMddHHmmss");
//        try {
//            ExcelUtils.exportExcel(exportVos, CompanyExportVo.class, fileName, new ExportParams(), response);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        fileName += ".xlsx";
        ExportParams excelParam = new ExportParams();
        try {
            ExcelUtils.exportExcel(exportVos, CompanyExportVo.class, fileName, excelParam, response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 跳转至Oms登录
     */
    @Override
    public String getTokenForOms(TokenForOmsReq req, HttpServletRequest request, Long userId) {
        if (req.getCompanyId() == null) throw new BizException(SysConstant.No_Data);
        Map<String, Object> map = new HashMap<>();
        map.put("id", req.getCompanyId());
        map.put("source", "omp");
        map.put("userId", userId);
        List<CompanyPageVo> list = dao.list(map);
        if (list.isEmpty()) throw new BizException(SysConstant.No_Data);
        UserDo userDo = userService.getById(list.get(0).getAdminAccountId());
        if (userDo == null) throw new BizException(SysConstant.No_Data);
        UserSession session = userSessionManager.createSession(userDo, "oms");

//        request.getSession().setAttribute(UserSession.SESSION_ID_KEY, session);
        return session.getSessionId();
    }

}
